#include "bluetooth_peripheral_service.h"
#include "bluetooth_app.h"
#include "app_vendor_model_srv.h"
#include "app.h"
 #include "gattprofile.h"
#include "app_vendor_model_cli.h"
/**
 * @brief 读属性回调
 *
 * @param ConnHandle     - 连接句柄
 * @param pGattAttribute - 属性句柄
 * @param pValue         - 返回目标属性读取的值
 * @param pLengthOut     - 读取数据长度
 * @param Offset         - 读取偏移量
 * @return uint8_t       - 操作状态
 */
static uint8_t ProfileReadAttrCallback(uint16_t ConnHandle, gattAttribute_t *pGattAttribute, uint8_t *pValue, uint16_t *pLengthOut, uint16_t Offset, uint16_t MaxLen, uint8_t Method);

/**
 * @brief 写属性回调
 *
 * @param ConnHandle     - 连接句柄
 * @param pGattAttribute - 属性句柄
 * @param pValue         - 写入参数
 * @param Length         - 写入参数长度
 * @param Offset         - 写入偏移量
 * @return uint8_t       - 操作状态
 */
static uint8_t ProfileWriteAttrCallback(uint16_t ConnHandle, gattAttribute_t *pGattAttribute, uint8_t *pValue, uint16_t Length, uint16_t Offset, uint8_t Method);

/**
 * @brief 链接状态更改处理
 *
 * @param ConnHandle - 连接句柄
 * @param ChangeType - 修改类型
 */
static void ProfileHandleConnectStatusCallback(uint16_t ConnHandle, uint8_t ChangeType);

static ProfileWriteHandle_t ProfileWriteHandleCallbakc = NULL;

const uint8_t ProfileServUUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16(PERIPHERAL_SERVICE_UUID),
    HI_UINT16(PERIPHERAL_SERVICE_UUID),
};

const uint8_t ProfilecharUUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16(PERIPHERAL_CHARACTERISTIC_UUID),
    HI_UINT16(PERIPHERAL_CHARACTERISTIC_UUID),
};

static uint8_t ProfileCharUserDesp[] = "notify\0";
static uint8_t ProfileChar[PERIPHERAL_CHARACTERISTIC_LENGTH] = {0};
static uint8_t ProfileCharProps = GATT_PROP_NOTIFY | GATT_PROP_WRITE;
static gattCharCfg_t ProfileCharConfig[PERIPHERAL_MAX_CONNECTION] = {0};

static const gattAttrType_t ProfileServic = {ATT_BT_UUID_SIZE, ProfileServUUID};



static gattAttribute_t ProfileAttrTable[] = {
   {
        {ATT_BT_UUID_SIZE, primaryServiceUUID},
        GATT_PERMIT_READ,
        0,
        (uint8_t *)&ProfileServic,
    },
    {
        {ATT_BT_UUID_SIZE, characterUUID},
        GATT_PERMIT_READ,
        0,
        &ProfileCharProps,
    },

    {
        {ATT_BT_UUID_SIZE, ProfilecharUUID},
        GATT_PERMIT_WRITE,
        0,
        ProfileChar,
    },


    {
        {ATT_BT_UUID_SIZE, clientCharCfgUUID},
        GATT_PERMIT_READ | GATT_PERMIT_WRITE,
        0,
        (uint8_t *)ProfileCharConfig,
    },

    {
        {ATT_BT_UUID_SIZE, charUserDescUUID},
        GATT_PERMIT_READ,
        0,
        ProfileCharUserDesp,
    }, 
};

/*********************************************************************
 * Profile Attributes - variables
 */
#if 0
// Simple GATT Profile Service UUID: 0xFFF0
const uint8_t simpleProfileServUUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFFF0), HI_UINT16 (0xFFF0)};

// Characteristic 1 UUID: 0xFFF1
const uint8_t simpleProfilechar1UUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFFF1), HI_UINT16 (0xFFF1)};

// Characteristic 2 UUID: 0xFFF2
const uint8_t simpleProfilechar2UUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFFF2), HI_UINT16 (0xFFF2)};

// Characteristic 3 UUID: 0xFFF3
const uint8_t simpleProfilechar3UUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFFF3), HI_UINT16 (0xFFF3)};

// Characteristic 4 UUID: 0xFFF4
const uint8_t simpleProfilechar4UUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFFF4), HI_UINT16 (0xFFF4)};

// Characteristic 5 UUID: 0xFFF5
const uint8_t simpleProfilechar5UUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFFF5), HI_UINT16 (0xFFF5)};
    
// Characteristic 6 UUID: 0xFF01
const uint8_t simpleProfilechar6UUID1[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (0xFF01), HI_UINT16 (0xFF01)};


// Simple Profile Service attribute
static const gattAttrType_t simpleProfileService1 = {ATT_BT_UUID_SIZE, simpleProfileServUUID1};

// Simple Profile Characteristic 1 Properties
static uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;//| GATT_PROP_NOTIFY;

// Characteristic 1 Value
static uint8_t simpleProfileChar1[247] = {0};
//static gattCharCfg_t simpleProfileChar1Config[PERIPHERAL_MAX_CONNECTION];

// Simple Profile Characteristic 1 User Description
static uint8_t simpleProfileChar1UserDesp[] = "Characteristic 1\0";

// Simple Profile Characteristic 2 Properties
static uint8_t simpleProfileChar2Props = GATT_PROP_READ;

// Characteristic 2 Value
static uint8_t simpleProfileChar2[1] = {0};

// Simple Profile Characteristic 2 User Description
static uint8_t simpleProfileChar2UserDesp[] = "Characteristic 2\0";

// Simple Profile Characteristic 3 Properties
static uint8_t simpleProfileChar3Props = GATT_PROP_WRITE;

// Characteristic 3 Value
static uint8_t simpleProfileChar3[21] = {0};

// Simple Profile Characteristic 3 User Description
static uint8_t simpleProfileChar3UserDesp[] = "Characteristic 3\0";

// Simple Profile Characteristic 4 Properties
static uint8_t simpleProfileChar4Props = GATT_PROP_NOTIFY;

// Characteristic 4 Value
static uint8_t simpleProfileChar4[247] = {0};

// Simple Profile Characteristic 4 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t simpleProfileChar4Config1[PERIPHERAL_MAX_CONNECTION];

// Simple Profile Characteristic 4 User Description
static uint8_t simpleProfileChar4UserDesp[] = "Characteristic 4\0";

// Simple Profile Characteristic 5 Properties
static uint8_t simpleProfileChar5Props = GATT_PROP_READ;

// Characteristic 5 Value
static uint8_t simpleProfileChar5[5] = {0};

// Simple Profile Characteristic 5 User Description
static uint8_t simpleProfileChar5UserDesp[] = "Characteristic 5\0";

// Simple Profile Characteristic 6 Properties
static uint8_t simpleProfileChar6Props = GATT_PROP_NOTIFY|GATT_PROP_WRITE|GATT_PROP_READ;

// Characteristic 6 Value
static uint8_t simpleProfileChar6[247] = {0};

// Simple Profile Characteristic 6 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t simpleProfileChar6Config1[PERIPHERAL_MAX_CONNECTION];

// Simple Profile Characteristic 6 User Description
static uint8_t simpleProfileChar6UserDesp[] = "Characteristic 6\0";


// Simple GATT Profile Service UUID: 0xFFF0
const uint8_t simpleProfileServiceT[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_SERV_UUID), HI_UINT16 (SIMPLEPROFILE_SERV_UUID)};

#if 1
 gattAttribute_t ProfileAttrTable[] = {
       // Simple Profile Service
    {
     {ATT_BT_UUID_SIZE, primaryServiceUUID},     /* type */
        GATT_PERMIT_READ, /* permissions */
        0, /* handle */
        (uint8_t *)&simpleProfileService1       /* pValue */
    },
#if 1
 // Characteristic 1 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar1Props },
  // Characteristic Value 1
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar1UUID1},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     simpleProfileChar1  },

 // Characteristic 1 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar1UserDesp },

 // Characteristic 2 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar2Props },

 // Characteristic Value 2
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar2UUID1},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar2},

 // Characteristic 2 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar2UserDesp  },

 // Characteristic 3 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar3Props  },

 // Characteristic Value 3
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar3UUID1},
     GATT_PERMIT_WRITE,
     0,
     simpleProfileChar3   },

 // Characteristic 3 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar3UserDesp },
#endif
 // Characteristic 4 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar4Props  },
  // Characteristic Value 4
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar4UUID1},
     0,
     0,
     simpleProfileChar4  },

 // Characteristic 4 configuration
    {
     {ATT_BT_UUID_SIZE, clientCharCfgUUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     (uint8_t *)simpleProfileChar4Config },

 // Characteristic 4 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar4UserDesp     },

  // Characteristic 5 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar5Props },

 // Characteristic Value 5
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar5UUID1},
     GATT_PERMIT_AUTHEN_READ,
     0,
     simpleProfileChar5  },

 // Characteristic 5 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar5UserDesp},

// Characteristic 6 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar6Props},
  // Characteristic Value 6
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar6UUID1},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     simpleProfileChar6    },
     // Characteristic 6 configuration
    {
     {ATT_BT_UUID_SIZE, clientCharCfgUUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     (uint8_t *)simpleProfileChar6Config  },

 // Characteristic 6 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar6UserDesp },

    
};
#endif



 gattAttribute_t simpleProfileAttrTbl1[] = {
    // Simple Profile Service
    {
     {ATT_BT_UUID_SIZE, primaryServiceUUID},     /* type */
        GATT_PERMIT_READ, /* permissions */
        0, /* handle */
        (uint8_t *)&simpleProfileServiceT        /* pValue */
    },
#if 1
 // Characteristic 1 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar1Props },
  // Characteristic Value 1
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar1UUID1},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     simpleProfileChar1  },

 // Characteristic 1 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar1UserDesp },

 // Characteristic 2 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar2Props },

 // Characteristic Value 2
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar2UUID1},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar2},

 // Characteristic 2 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar2UserDesp  },

 // Characteristic 3 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar3Props  },

 // Characteristic Value 3
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar3UUID1},
     GATT_PERMIT_WRITE,
     0,
     simpleProfileChar3   },

 // Characteristic 3 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar3UserDesp },
#endif
 // Characteristic 4 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar4Props  },
  // Characteristic Value 4
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar4UUID1},
     0,
     0,
     simpleProfileChar4  },

 // Characteristic 4 configuration
    {
     {ATT_BT_UUID_SIZE, clientCharCfgUUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     (uint8_t *)simpleProfileChar4Config  },

 // Characteristic 4 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar4UserDesp     },

  // Characteristic 5 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar5Props },

 // Characteristic Value 5
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar5UUID1},
     GATT_PERMIT_AUTHEN_READ,
     0,
     simpleProfileChar5  },

 // Characteristic 5 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar5UserDesp},

// Characteristic 6 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar6Props},
  // Characteristic Value 6
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar6UUID1},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     simpleProfileChar6    },
     // Characteristic 6 configuration
    {
     {ATT_BT_UUID_SIZE, clientCharCfgUUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     (uint8_t *)simpleProfileChar6Config  },

 // Characteristic 6 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar6UserDesp },

};
#endif

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */

//static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;

// Simple GATT Profile Service UUID: 0xFFF0
const uint8_t simpleProfileServUUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_SERV_UUID), HI_UINT16 (SIMPLEPROFILE_SERV_UUID)};

// Characteristic 1 UUID: 0xFFF1
const uint8_t simpleProfilechar1UUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_CHAR1_UUID), HI_UINT16 (SIMPLEPROFILE_CHAR1_UUID)};

// Characteristic 2 UUID: 0xFFF2
const uint8_t simpleProfilechar2UUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_CHAR2_UUID), HI_UINT16 (SIMPLEPROFILE_CHAR2_UUID)};

// Characteristic 3 UUID: 0xFFF3
const uint8_t simpleProfilechar3UUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_CHAR3_UUID), HI_UINT16 (SIMPLEPROFILE_CHAR3_UUID)};

// Characteristic 4 UUID: 0xFFF4
const uint8_t simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_CHAR4_UUID), HI_UINT16 (SIMPLEPROFILE_CHAR4_UUID)};

// Characteristic 5 UUID: 0xFFF5
const uint8_t simpleProfilechar5UUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_CHAR5_UUID), HI_UINT16 (SIMPLEPROFILE_CHAR5_UUID)};
    
// Characteristic 6 UUID: 0xFF01
const uint8_t simpleProfilechar6UUID[ATT_BT_UUID_SIZE] = {
    LO_UINT16 (SIMPLEPROFILE_CHAR6_UUID), HI_UINT16 (SIMPLEPROFILE_CHAR6_UUID)};




/*********************************************************************
 * Profile Attributes - variables
 */

// Simple Profile Service attribute
static const gattAttrType_t simpleProfileService = {ATT_BT_UUID_SIZE, simpleProfileServUUID};

// Simple Profile Characteristic 1 Properties
static uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;//| GATT_PROP_NOTIFY;

// Characteristic 1 Value
static uint8_t simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = {0};
//static gattCharCfg_t simpleProfileChar1Config[PERIPHERAL_MAX_CONNECTION];

// Simple Profile Characteristic 1 User Description
static uint8_t simpleProfileChar1UserDesp[] = "Characteristic 1\0";

// Simple Profile Characteristic 2 Properties
static uint8_t simpleProfileChar2Props = GATT_PROP_READ;

// Characteristic 2 Value
static uint8_t simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] = {0};

// Simple Profile Characteristic 2 User Description
static uint8_t simpleProfileChar2UserDesp[] = "Characteristic 2\0";

// Simple Profile Characteristic 3 Properties
static uint8_t simpleProfileChar3Props = GATT_PROP_WRITE;

// Characteristic 3 Value
static uint8_t simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = {0};

// Simple Profile Characteristic 3 User Description
static uint8_t simpleProfileChar3UserDesp[] = "Characteristic 3\0";

// Simple Profile Characteristic 4 Properties
static uint8_t simpleProfileChar4Props = GATT_PROP_NOTIFY;

// Characteristic 4 Value
static uint8_t simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = {0};

// Simple Profile Characteristic 4 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t simpleProfileChar4Config[PERIPHERAL_MAX_CONNECTION];

// Simple Profile Characteristic 4 User Description
static uint8_t simpleProfileChar4UserDesp[] = "Characteristic 4\0";

// Simple Profile Characteristic 5 Properties
static uint8_t simpleProfileChar5Props = GATT_PROP_READ;

// Characteristic 5 Value
static uint8_t simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = {0};

// Simple Profile Characteristic 5 User Description
static uint8_t simpleProfileChar5UserDesp[] = "Characteristic 5\0";

// Simple Profile Characteristic 6 Properties
static uint8_t simpleProfileChar6Props = GATT_PROP_NOTIFY|GATT_PROP_WRITE|GATT_PROP_READ;

// Characteristic 6 Value
static uint8_t simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = {0};

// Simple Profile Characteristic 6 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
 gattCharCfg_t simpleProfileChar6Config[PERIPHERAL_MAX_CONNECTION];

// Simple Profile Characteristic 6 User Description
static uint8_t simpleProfileChar6UserDesp[] = "Characteristic 6\0";
/*********************************************************************
 * Profile Attributes - Table
 */

 gattAttribute_t simpleProfileAttrTbl[] = {
    // Simple Profile Service
    {
     {ATT_BT_UUID_SIZE, primaryServiceUUID},     /* type */
        GATT_PERMIT_READ, /* permissions */
        0, /* handle */
        (uint8_t *)&simpleProfileService        /* pValue */
    },
#if 1
 // Characteristic 1 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar1Props },
  // Characteristic Value 1
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar1UUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     simpleProfileChar1  },

 // Characteristic 1 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar1UserDesp },

 // Characteristic 2 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar2Props },

 // Characteristic Value 2
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar2UUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar2},

 // Characteristic 2 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar2UserDesp  },

 // Characteristic 3 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar3Props  },

 // Characteristic Value 3
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar3UUID},
     GATT_PERMIT_WRITE,
     0,
     simpleProfileChar3   },

 // Characteristic 3 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar3UserDesp },
#endif
 // Characteristic 4 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar4Props  },
  // Characteristic Value 4
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar4UUID},
     0,
     0,
     simpleProfileChar4  },

 // Characteristic 4 configuration
    {
     {ATT_BT_UUID_SIZE, clientCharCfgUUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     (uint8_t *)simpleProfileChar4Config  },

 // Characteristic 4 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar4UserDesp     },

  // Characteristic 5 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar5Props },

 // Characteristic Value 5
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar5UUID},
     GATT_PERMIT_AUTHEN_READ,
     0,
     simpleProfileChar5  },

 // Characteristic 5 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar5UserDesp},

// Characteristic 6 Declaration
    {
     {ATT_BT_UUID_SIZE, characterUUID},
     GATT_PERMIT_READ,
     0,
     &simpleProfileChar6Props},
  // Characteristic Value 6
    {
     {ATT_BT_UUID_SIZE, simpleProfilechar6UUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     simpleProfileChar6    },
     // Characteristic 6 configuration
    {
     {ATT_BT_UUID_SIZE, clientCharCfgUUID},
     GATT_PERMIT_READ | GATT_PERMIT_WRITE,
     0,
     (uint8_t *)simpleProfileChar6Config  },

 // Characteristic 6 User Description
    {
     {ATT_BT_UUID_SIZE, charUserDescUUID},
     GATT_PERMIT_READ,
     0,
     simpleProfileChar6UserDesp },

};

static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
gattServiceCBs_t ProfileCallback = {
    ProfileReadAttrCallback,
    ProfileWriteAttrCallback,
    NULL,
};

static uint8_t ProfileReadAttrCallback(uint16_t ConnHandle, gattAttribute_t *pGattAttribute, uint8_t *pValue, uint16_t *pLengthOut, uint16_t Offset, uint16_t MaxLen, uint8_t Method)
{
  uint8_t ReadAttrResult = SUCCESS;
  uint8_t i=0;
  uint16_t UUID = BUILD_UINT16(pGattAttribute->type.uuid[0], pGattAttribute->type.uuid[1]);
  PRINT("profile ChangeCB CHAR1.. \n");
  if (Offset > 0)
    return ATT_ERR_ATTR_NOT_LONG;

  if (pGattAttribute->type.len == ATT_BT_UUID_SIZE)
  {
    switch (UUID)
    {
    case PERIPHERAL_CHARACTERISTIC_UUID:
    {
      *pLengthOut = PERIPHERAL_CHARACTERISTIC_LENGTH;
      memcpy(pValue, pGattAttribute->pValue, PERIPHERAL_CHARACTERISTIC_LENGTH);
    }
    break;

    default:
    {
      *pLengthOut = 0;
      ReadAttrResult = ATT_ERR_ATTR_NOT_FOUND;
    }
    break;
    }
  }
  else
  {
    *pLengthOut = 0;
    ReadAttrResult = ATT_ERR_INVALID_HANDLE;
  }

  return ReadAttrResult;
}



static uint8_t ProfileWriteAttrCallback(uint16_t ConnHandle, gattAttribute_t *pGattAttribute, uint8_t *pValue, uint16_t LengthIn, uint16_t Offset, uint8_t Method)
{
  uint8_t WriteAttrResult = ATT_ERR_INVALID_HANDLE, NotifyApp = 0xFF;
  uint16_t UUID = BUILD_UINT16(pGattAttribute->type.uuid[0], pGattAttribute->type.uuid[1]);
  uint16_t i=0;
  bStatus_t status = SUCCESS;
  uint8_t notifyApp = 0xFF;
  PRINT("profile ChangeCB CHAR2.. \n");
  if (gattPermitAuthorWrite(pGattAttribute->permissions))
    return ATT_ERR_INSUFFICIENT_AUTHOR;
  if (pGattAttribute->type.len == ATT_BT_UUID_SIZE)
  {
    printf("UUID %04x  len %0d\r\n",UUID,LengthIn);
    printf("recvdate: ");
    for(i=0;i<LengthIn;i++)
    {
      printf("%02x",pValue[i]);
    }
    switch (UUID)
    {
      case 0xFFE1:
        printf("recvdatefor ffe1: ");
        simpleProfileChangeCB(0,pValue,LengthIn);
        notifyApp = 1;
      break;
      case GATT_CLIENT_CHAR_CFG_UUID:
      {
//        WriteAttrResult = GATTServApp_ProcessCCCWriteReq(ConnHandle, pGattAttribute, pValue, LengthIn, Offset, GATT_CLIENT_CFG_NOTIFY);
          WriteAttrResult = GATTServApp_ProcessCCCWriteReq(ConnHandle, pGattAttribute, pValue, LengthIn,
                                                        Offset, GATT_CLIENT_CFG_NOTIFY);
      }
      break;

      case PERIPHERAL_CHARACTERISTIC_UUID:
      {
        WriteAttrResult = SUCCESS;
        // printf("get date \r\n");
        // for(i=0;i<10;i++)
        // {
        //     printf(" %02x ",pValue[i]);
        // }
        // printf("out\r\n");
/*        if (ProfileWriteHandleCallbakc != NULL)
        {
          ProfileWriteHandleCallbakc(pValue, LengthIn);
        }*/
        PeripheralHostWriteDataHandler(pValue,LengthIn);
        notifyApp = 6;
      }
      break;
      default:
      {
        WriteAttrResult = ATT_ERR_ATTR_NOT_FOUND;
      }
      break;
      }
  }
  return WriteAttrResult;
}

/*********************************************************************
 * @fn      simpleProfileChangeCB
 *
 * @brief   Callback from SimpleBLEProfile indicating a value change
 *
 * @param   paramID - parameter ID of the value that was changed.
 *          pValue - pointer to data that was changed
 *          len - length of data
 *
 * @return  none
 */
 void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
{
    uint8_t i=0;
    switch(paramID)
    {
        case 0x00:
        {
            
            PRINT("profile ChangeCB CHAR1.. \n");
 //           App_peripheral_reveived(pValue, len);
            uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
            tmos_memcpy(newValue, pValue, len);
            PRINT("profile ChangeCB CHAR1.. \n");
            APP_DBG("node1_addr %x", app_nodes[1].node_addr);
            if(app_nodes[1].node_addr==2)
            {
                printf("111111\r\n");
                uint8_t           status;
                struct send_param param = {
                   .app_idx = self_prov_app_idx,     // 此消息使用的app key
                    .addr = app_nodes[1].node_addr,   // 此消息发往的目的地地址，此处为第一个配网的节点
                    .trans_cnt = 0x03,                // 此消息的重传次数
                    .period = K_MSEC(400),            // 此消息重传的间隔，建议不小于(200+50*TTL)ms，若数据较大则建议加长
                    .rand = (0),                      // 此消息发送的随机延迟
                    .tid = vendor_cli_tid_get(),      // tid，每个独立消息递增循环，cli使用0~127
                    .send_ttl = BLE_MESH_TTL_DEFAULT, // ttl，无特定则使用默认值
                };
                status = vendor_message_cli_write(&param, newValue, len); // 调用自定义模型客户端的有应答写函数发送数据
               printf("Status %0d\r\n",status);
                if(status)
                    APP_DBG("write failed %d", status);
            }

            for(i=0;i<len;i++)
            {
                printf(" %02x ",pValue[i]);
            }
//            SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, newValue);
//            PRINT("profile ChangeCB CHAR1.. \n");
            break;
        }

        case 0x03:
        {
            uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
            tmos_memcpy(newValue, pValue, len);
            PRINT("profile ChangeCB CHAR3..\n");
            APP_DBG("node2_addr %x", app_nodes[2].node_addr);
            if(app_nodes[2].node_addr)
            {
                uint8_t           status;
                struct send_param param = {
                  .app_idx = self_prov_app_idx,     // 此消息使用的app key
                    .addr = app_nodes[2].node_addr,   // 此消息发往的目的地地址，此处为第二个配网的节点
                    .trans_cnt = 0x03,                // 此消息的重传次数
                    .period = K_MSEC(400),            // 此消息重传的间隔，建议不小于(200+50*TTL)ms，若数据较大则建议加长
                    .rand = (0),                      // 此消息发送的随机延迟
                    .tid = vendor_cli_tid_get(),      // tid，每个独立消息递增循环，cli使用0~127
                    .send_ttl = BLE_MESH_TTL_DEFAULT, // ttl，无特定则使用默认值
                };
                status = vendor_message_cli_write(&param, newValue, len); // 调用自定义模型客户端的有应答写函数发送数据
                if(status)
                    APP_DBG("write failed %d", status);
            }
            break;
        }

        default:
            // should not reach here!
            break;
    }
}
static void ProfileHandleConnectStatusCallback(uint16_t ConnHandle, uint8_t ChangeType)
{
  if (ConnHandle != LOOPBACK_CONNHANDLE)
  {
    if ((ChangeType == LINKDB_STATUS_UPDATE_REMOVED) 
    || ((ChangeType == LINKDB_STATUS_UPDATE_STATEFLAGS) && 
    (!linkDB_Up(ConnHandle))))
    {
//      GATTServApp_InitCharCfg(ConnHandle, ProfileCharConfig);
      GATTServApp_InitCharCfg(ConnHandle, simpleProfileChar4Config);
    }
  }
}

uint8_t ProfileSetParameter(uint8_t Parameter, uint8_t Length, void *pDataIn)
{
  uint8_t SetResult = bleInvalidRange;

  switch (Parameter)
  {
  case PERIPHERAL_CHARACTERISTIC_ID:
  {
    if (Length == PERIPHERAL_CHARACTERISTIC_LENGTH)
    {
      SetResult = SUCCESS;
      tmos_memcpy(ProfileChar, pDataIn, PERIPHERAL_CHARACTERISTIC_LENGTH);
    }
  }
  break;

  default:
  {
    SetResult = INVALIDPARAMETER;
  }
  break;
  }

  return SetResult;
}

uint8_t ProfileGetParameter(uint8_t Parameter, void *pDataOut)
{
  uint8_t GetResult = SUCCESS;
  switch (Parameter)
  {
  case PERIPHERAL_CHARACTERISTIC_ID:
  {
    tmos_memcpy(pDataOut, ProfileChar, PERIPHERAL_CHARACTERISTIC_LENGTH);
  }
  break;

  default:
  {
    GetResult = INVALIDPARAMETER;
  }
  break;
  }

  return GetResult;
}

#define SIMPLEPROFILE_CHAR4_VALUE_POS 11
#define SIMPLEPROFILE_CHAR6_VALUE_POS 18


/*********************************************************************
 * @fn          simpleProfile_HandleConnStatusCB
 *
 * @brief       Simple Profile link status change handler function.
 *
 * @param       connHandle - connection handle
 * @param       changeType - type of change
 *
 * @return      none
 */
 void simpleProfile_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType)
{
    // Make sure this is not loopback connection
    if(connHandle != LOOPBACK_CONNHANDLE)
    {
        // Reset Client Char Config if connection has dropped
        if((changeType == LINKDB_STATUS_UPDATE_REMOVED) ||
           ((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS) &&
            (!linkDB_Up(connHandle))))
        {
            GATTServApp_InitCharCfg(connHandle, simpleProfileChar4Config);
            GATTServApp_InitCharCfg(connHandle, simpleProfileChar6Config);
        }
    }
}


/*********************************************************************
 * LOCAL VARIABLES
 */
static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing

// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] = {
    // complete name
    0x02, // length of this data
    GAP_ADTYPE_LOCAL_NAME_COMPLETE,
    'T',
 //   'G',
 //   'L',
//    'O',
 //   'C',
 //   'K',

    // connection interval range
    0x05, // length of this data
    GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
    LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
    HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
    LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
    HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),

    // Tx power level
    0x02, // length of this data
    GAP_ADTYPE_POWER_LEVEL,
    0 // 0dBm
};

// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertising)
static uint8_t advertData[] = {
    // Flags; this sets the device to use limited discoverable
    // mode (advertises for 30 seconds at a time) instead of general
    // discoverable mode (advertises indefinitely)
    0x02, // length of this data
    GAP_ADTYPE_FLAGS,
    DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

    // service UUID, to notify central devices what services are included
    // in this peripheral
    0x03,                  // length of this data
    GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
    LO_UINT16(SIMPLEPROFILE_SERV_UUID),
    HI_UINT16(SIMPLEPROFILE_SERV_UUID),

    0x05,                  // length of this data
    GAP_ADTYPE_MANUFACTURER_SPECIFIC,
    0xD7,
    0x07,
    0x00,
    0x00
};

// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Peripheral";

void Peripheral_Init(void)
{
    uint8_t result=0;
    PeripheralTaskId = TMOS_ProcessEventRegister(PeripheralProcessEvent);

    // Setup the GAP Peripheral Role Profile
    {
/*         uint8_t  initial_advertising_enable = TRUE;
        uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;

        // Set the GAP Role Parameters
         GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
         GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
         GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
         GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
         GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);*/
       uint16_t DesiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t DesiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint8_t i=0;
        PeripheralLoadRelatedParameters();
        // GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, (uint8_t[]){true});
        Set_Peripheral_Status(false);
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, NumberOfScanRspData, ScanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, NumberOfAdvertData, AdvertData);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &DesiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &DesiredMaxInterval);
    }

    // Set advertising interval
    {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;

        GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
    }

    // Setup the GAP Bond Manager
    {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t  pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t  mitm = TRUE;
        uint8_t  bonding = TRUE;
        uint8_t  ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
    }

    // Initialize GATT attributes
    GGS_AddService(GATT_ALL_SERVICES);           // GAP
    GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
    result=SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    // Set the GAP Characteristics
    GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);

    // Init Connection Item
    PeripheralInitConnItem();

    // Register receive scan request callback
    GAPRole_BroadcasterSetCB(&BroadcasterBroadcasterCallback);
    // Setup a delayed profile startup
    result=tmos_set_event(PeripheralTaskId, BLUETOOTH_START_DEVICE_EVENT);
    
}






/*********************************************************************
 * @fn          simpleProfile_Notify
 *
 * @brief       Send a notification containing a heart rate
 *              measurement.
 *
 * @param       connHandle - connection handle
 * @param       pNoti - pointer to notification structure
 *
 * @return      Success or Failure
 */
bStatus_t simpleProfile_Notify(uint16_t connHandle, attHandleValueNoti_t *pNoti)
{
    uint16_t value = GATTServApp_ReadCharCfg(connHandle, simpleProfileChar4Config);
    // If notifications enabled
    if(value & GATT_CLIENT_CFG_NOTIFY)
    {
        // Set the handle
        pNoti->handle = simpleProfileAttrTbl[SIMPLEPROFILE_CHAR4_VALUE_POS].handle;

        // Send the notification
        return GATT_Notification (connHandle, pNoti, FALSE);
    }
    return bleIncorrectMode;
}

/*********************************************************************
 * @fn          simpleProfile_Notify_Char
 *
 * @brief       Send a notification containing a heart rate
 *              measurement.
 *
 * @param       connHandle - connection handle
 * @param       pNoti - pointer to notification structure
 *
 * @return      Success or Failure
 */
bStatus_t simpleProfile_Notify_Char6(uint16_t connHandle, attHandleValueNoti_t *pNoti)
{
    uint16_t value = GATTServApp_ReadCharCfg(connHandle, simpleProfileChar6Config);

    // If notifications enabled
    if(value & GATT_CLIENT_CFG_NOTIFY)
    {
        // Set the handle
        pNoti->handle = simpleProfileAttrTbl[SIMPLEPROFILE_CHAR6_VALUE_POS].handle;

        // Send the notification
        return GATT_Notification (connHandle, pNoti, FALSE);
    }
    return bleIncorrectMode;
}

/*********************************************************************
 * @fn      SimpleProfile_AddService
 *
 * @brief   Initializes the Simple Profile service by registering
 *          GATT attributes with the GATT server.
 *
 * @param   services - services to add. This is a bit map and can
 *                     contain more than one service.
 *
 * @return  Success or Failure
 */
bStatus_t SimpleProfile_AddService(uint32_t services)
{
    uint8_t status = SUCCESS;
    // Initialize Client Characteristic Configuration attributes
    GATTServApp_InitCharCfg(INVALID_CONNHANDLE, simpleProfileChar4Config);
    GATTServApp_InitCharCfg(INVALID_CONNHANDLE, simpleProfileChar6Config);

    // Register with Link DB to receive link status change callback
    linkDB_Register(simpleProfile_HandleConnStatusCB);

//    if(services & SIMPLEPROFILE_SERVICE)
    {
        // Register GATT attribute list and CBs with GATT Server App
        status = GATTServApp_RegisterService(simpleProfileAttrTbl,
                                             GATT_NUM_ATTRS(simpleProfileAttrTbl),
                                             GATT_MAX_ENCRYPT_KEY_SIZE,
                                             &ProfileCallback);//&simpleProfileCBs);
    }

    return (status);
}

void Set_Peripheral_Status(uint8_t Status)
{
     GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, (uint8_t[]){Status});
}

#if 0
/*********************************************************************
 * @fn      Peripheral_AdvertData_Privisioned
 *
 * @brief   修改广播数据内配网标志.
 *
 * @param   privisioned - 是否已配网
 *
 * @return  none
 */
void Peripheral_AdvertData_Privisioned(uint8_t privisioned)
{
    uint8_t  advertising_enable;
    if(privisioned)
    {
        AdvertData[11]=0x01;
        AdvertData[12]=0x00;
    }
    else
    {
        AdvertData[11]=0x00;
        AdvertData[12]=0x00;
    }
    GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advertising_enable);
    if(advertising_enable)
    {
        advertising_enable = FALSE;
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(AdvertData), AdvertData);
        advertising_enable = TRUE;
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
    }
    else
    {
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(AdvertData), AdvertData);
    }
}




#endif